﻿using System;
using MediaPortal.GUI.Library;
using MediaPortal.Dialogs;
using MediaPortal.Core;
using WindowPlugins.GUITVSeries;
using System.ComponentModel;
using System.Threading;
using System.Text.RegularExpressions;
using System.Collections.Generic;


namespace MyShowsPlugin
{
    public class MyShowsPlugin : GUIWindow, ISetupForm
    {
        [SkinControlAttribute(50)]
        protected GUIListControl UpcomingList = null;

        BackgroundWorker syncLibraryWorker;
        static Timer syncLibraryTimer;

        #region ISetupForm Members

        // Returns the name of the plugin which is shown in the plugin menu
        public string PluginName()
        {
            return "MyShowsPlugin";
        }

        // Returns the description of the plugin is shown in the plugin menu
        public string Description()
        {
            return "MyShows.ru Scrobbler Plugin";
        }

        // Returns the author of the plugin which is shown in the plugin menu
        public string Author()
        {
            return "Edalex, Silent_Sky";
        }

        // show the setup dialog
        public void ShowPlugin()
        {
            Configuration conf = new Configuration();
            conf.ShowDialog();


        }

        // Indicates whether plugin can be enabled/disabled
        public bool CanEnable()
        {
            return true;
        }

        // Get Windows-ID
        public int GetWindowId()
        {
            // WindowID of windowplugin belonging to this setup
            // enter your own unique code
            return 1507;
        }

        public override int GetID
        {
            get
            {
                return 1507;
            }
            set
            {
               
            }
        }

        // Indicates if plugin is enabled by default;
        public bool DefaultEnabled()
        {
            return true;
        }

        // indicates if a plugin has it's own setup screen
        public bool HasSetup()
        {
            return true;
        }

        /// <summary>
        /// If the plugin should have it's own button on the main menu of MediaPortal then it
        /// should return true to this method, otherwise if it should not be on home
        /// it should return false
        /// </summary>
        /// <param name="strButtonText">text the button should have</param>
        /// <param name="strButtonImage">image for the button, or empty for default</param>
        /// <param name="strButtonImageFocus">image for the button, or empty for default</param>
        /// <param name="strPictureImage">subpicture for the button or empty for none</param>
        /// <returns>true : plugin needs it's own button on home
        /// false : plugin does not need it's own button on home</returns>

        public bool GetHome(out string strButtonText, out string strButtonImage,
          out string strButtonImageFocus, out string strPictureImage)
        {
            strButtonText = PluginName();
            strButtonImage = String.Empty;
            strButtonImageFocus = String.Empty;
            strPictureImage = String.Empty;
            return true;
        }

        // With GetID it will be an window-plugin / otherwise a process-plugin
        // Enter the id number here again


        #endregion
        public override bool Init()
        {
            //syncLibraryTimer = new Timer(new TimerCallback((o) => { Sync(); }), null, 1 * 60 * 1000, 24 * 3600 * 1000);
            VideoHandler.EpisodeWatched += new VideoHandler.EpisodeWatchedDelegate(MyShowUtility.Instance.OnEpisodeWatched);
            PlayListPlayer.EpisodeWatched += new PlayListPlayer.EpisodeWatchedDelegate(MyShowUtility.Instance.OnEpisodeWatched);
            TVSeriesPlugin.ToggleWatched += new TVSeriesPlugin.ToggleWatchedEventDelegate(MyShowUtility.Instance.OnToggleWatched);
            
            return Load(GUIGraphicsContext.Skin + @"\MyShowsPlugin.xml");
        }

        protected override void OnPageLoad()
        {
            FillFacade();
            base.OnPageLoad();
        }

        void FillFacade()
        {
            MyShowUtility.Instance.Auth();
            List<MyShowsSeries> myshows = MyShowUtility.Instance.MyWatchedShows();
            List<Episode> upcoming = MyShowUtility.Instance.UpcomingEpisodes();
            foreach (Episode e in upcoming)
            {
                GUIListItem item = new GUIListItem();
                MyShowsSeries show = myshows.Find(y => y.showid == e.showId);
                item.Label = string.Format("{0} {1}x{2} {3}", (!string.IsNullOrEmpty(show.ruTitle) ? show.ruTitle : show.title), e.seasonNumber, e.episodeNumber, e.title);
                item.Label2 = e.airDate;
                item.AlbumInfoTag = show;
                item.ThumbnailImage = show.image;
                item.OnItemSelected += OnItemChanged;
                UpcomingList.Add(item);
            }

            GUIPropertyManager.SetProperty("#Show.CoverArt", (UpcomingList[0].AlbumInfoTag as MyShowsSeries).image);

        }

        public override void OnAction(MediaPortal.GUI.Library.Action action)
        {

            base.OnAction(action);
        }

        void OnItemChanged(GUIListItem item, GUIControl parent)
        {
            GUIPropertyManager.SetProperty("#Show.CoverArt", (UpcomingList.SelectedListItem.AlbumInfoTag as MyShowsSeries).image);
        }
           
        public override void DeInit()
        {
            VideoHandler.EpisodeWatched -= new VideoHandler.EpisodeWatchedDelegate(MyShowUtility.Instance.OnEpisodeWatched);
            PlayListPlayer.EpisodeWatched -= new PlayListPlayer.EpisodeWatchedDelegate(MyShowUtility.Instance.OnEpisodeWatched);
            TVSeriesPlugin.ToggleWatched -= new TVSeriesPlugin.ToggleWatchedEventDelegate(MyShowUtility.Instance.OnToggleWatched);
            if (syncLibraryWorker != null)
            {
                syncLibraryWorker.CancelAsync();
            }
        }
        public void Sync()
        {
            if (syncLibraryWorker != null && syncLibraryWorker.IsBusy)
                return;

            syncLibraryWorker = new BackgroundWorker();
            syncLibraryWorker.DoWork += new DoWorkEventHandler(syncLibraryWorker_DoWork);
            syncLibraryWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(syncLibraryWorker_RunWorkerCompleted);
            syncLibraryWorker.WorkerSupportsCancellation = true;
            syncLibraryWorker.RunWorkerAsync();
        }
        private void syncLibraryWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (string.IsNullOrEmpty(Thread.CurrentThread.Name))
                Thread.CurrentThread.Name = "MyShows Sync";
        }
        private void syncLibraryWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Thread.CurrentThread.Name = "MyShows Sync";
            MyShowUtility.Instance.Auth();

            #region get data from myshows.ru
            //get shows list
            //List<Show> myshows = MyShowUtility.Instance.MyWatchedShows();
            //get wathed episodes

            #endregion
            #region get data from mp-tvseries
            //List<DBEpisode> localAllEpisodes = new List<DBEpisode>();
            //List<DBEpisode> localCollectionEpisodes = new List<DBEpisode>();
            //List<DBEpisode> localWatchedEpisodes = new List<DBEpisode>();
            // store list of series ids so we can update the episode counts
            // of any series that syncback watched flags
            List<int> seriesToUpdateEpisodeCounts = new List<int>();
            List<DBOnlineSeries> alllocalshows = DBOnlineSeries.getAllSeries();


            #endregion

            //iterating thru local series and syncing status       
            foreach (DBOnlineSeries s in alllocalshows)
            {
                //Thread AutoSearch = new Thread(delegate()
                // {
                     DBSeries mytv = Helper.getCorrespondingSeries(s[DBOnlineSeries.cID]);
                     if (mytv != null)
                     {
                        string ishidden = mytv[DBSeries.cHidden];
                        if (ishidden != "1")
                        {
                            Log.Instance().Print("series " + mytv[DBOnlineSeries.cPrettyName]);
                            //get all episodes
                            var conditions = new SQLCondition();
                            conditions.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, s[DBOnlineSeries.cID], SQLConditionType.Equal);
                            var epis = DBEpisode.Get(conditions, false);
                            epis.Sort();
                            //finding series online
                            string series = s[DBOnlineSeries.cOriginalName];
                            if (Regex.IsMatch(series,@".*(\d{4})"))
                            {
                                series = series.Remove(series.Length - 7);
                            }
                            MyShowsSeries currentshow = MyShowUtility.Instance.GetOnlineShow(series, mytv.Year);

                            if (currentshow == null)
                            {
                                series = s[DBOnlineSeries.cPrettyName];
                                if (Regex.IsMatch(series, @".*(\d{4})"))
                                {
                                    series = series.Remove(series.Length - 7);
                                }
                                currentshow = MyShowUtility.Instance.GetOnlineShow(series, mytv.Year);
 
                            }
                            try
                            {
                                Log.Instance().Print("series found " + currentshow.ruTitle + " " + currentshow.id);
                            }
                            catch { }
                            if (currentshow == null) return;
                            List<Episode> alleps = new List<Episode>();
                            foreach (KeyValuePair<string, Episode> item in currentshow.episodes)
                            {
                                alleps.Add(item.Value);
                            }
                            //getting watched eps list
                            List<WatchedEps> onlinewatchedlist = MyShowUtility.Instance.GetWatched(currentshow.id);
                            foreach (DBEpisode epi in epis)
                            {
                                if (epi[DBEpisode.cCompositeID] == "248742_2x15")
                                {
                                    //d
                                }
                                bool watchedlocal = false;
                                //watchedlocal = (epi[DBOnlineEpisode.cWatched] == "1" ? true : false);
                                Log.Instance().Print("watched local " + epi[DBEpisode.cCompositeID] + " " + watchedlocal.ToString());
                                Episode foundep = alleps.Find(x => x.seasonNumber == (int)epi[DBEpisode.cSeasonIndex] && x.episodeNumber == (int)epi[DBEpisode.cEpisodeIndex]);
                                int onlineEpId = (foundep != null ? foundep.id : 0);
                                if (onlineEpId != 0)
                                {
                                    MyShowsEpisode onlineep = new MyShowsEpisode();
                                    onlineep.episode = onlineEpId;
                                    onlineep.seriesID = currentshow.id;
                                    bool watchedonline = false;
                                    //watchedonline = onlinewatchedlist.Exists(y => y.id == onlineEpId);
                                    Log.Instance().Print("watched online " + watchedonline.ToString());
                                    if (watchedlocal & !watchedonline)
                                    {
                                        Log.Instance().Print("Marking watched on MyShows");
                                        MyShowUtility.Instance.MarkWatched(onlineEpId);
                                    }
                                    if (!watchedlocal & watchedonline)
                                    {
                                        Log.Instance().Print("Marking watched in MP-TVSeries");
                                        epi[DBOnlineEpisode.cWatched] = true;
                                        epi.Commit();
                                    }
                                }
                                else
                                {
                                    //Log.Instance().Print(string.Format("onlineepId {0} foundep {1} seasson {2} episdoe {3}", onlineEpId, foundep.ToString(), (int)epi[DBEpisode.cEpisodeIndex], (int)epi[DBEpisode.cEpisodeIndex]));
                                }
                            }

                        }
                     }
            //     })
            //{
            //    IsBackground = true,
            //    Name = "MyTorrents Autograbber"
            //};
            //    AutoSearch.Start();
            }
        }


    }
}
 

